package com.xuecheng.auth.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;

import javax.annotation.Resource;

/**
 * @author VectorX
 * @version 1.0.0
 * @description OAuth2.0授权服务器配置
 * @date 2024/04/24
 * @see AuthorizationServerConfigurerAdapter
 */
@Configuration
// 启用 OAuth2.0 授权服务器功能
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter
{

    @Resource(name = "authorizationServerTokenServicesCustom")
    private AuthorizationServerTokenServices authorizationServerTokenServices;

    @Autowired
    private AuthenticationManager authenticationManager;

    /**
     * 客户端详情服务
     *
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()// 使用in-memory存储
               .withClient("XcWebApp")// client_id
               // .secret("XcWebApp")//客户端密钥
               .secret(new BCryptPasswordEncoder().encode("XcWebApp"))//客户端密钥
               .resourceIds("xuecheng-plus")//资源列表
               .authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit",
                       "refresh_token")// 该client允许的授权类型authorization_code,password,refresh_token,implicit,client_credentials
               .scopes("all")// 允许的授权范围
               .autoApprove(false)//false跳转到授权页面
               //客户端接收授权码的重定向地址
               .redirectUris("http://www.51xuecheng.cn");
    }

    /**
     * 令牌端点的访问配置
     *
     * @param endpoints
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.authenticationManager(authenticationManager)//认证管理器
                 .tokenServices(authorizationServerTokenServices)//令牌管理服务
                 .allowedTokenEndpointRequestMethods(HttpMethod.POST);
    }

    /**
     * 令牌端点的安全配置
     *
     * @param security
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security.tokenKeyAccess("permitAll()")                    //oauth/token_key是公开
                .checkTokenAccess("permitAll()")                  //oauth/check_token公开
                .allowFormAuthenticationForClients()                //表单认证（申请令牌）
        ;
    }

}
